using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Graphics.PackedVector;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;


namespace WPCoco.Graphics
{
    public class Graphic
    {
        public Graphic()
        {
            //basicEffect = new BasicEffect(Screen.CurrentGraphicsDevice);
            //basicEffect.VertexColorEnabled = true;
            //basicEffect.TextureEnabled = true;
            ////basicEffect.Projection = Matrix.CreateOrthographicOffCenter(0, Screen.Width,     // left, right
            ////                                                            Screen.Height, 0,    // bottom, top
            ////                                                            0.1f, 1000);

            //basicEffect.Projection = ProjectionMatrix = Matrix.CreateOrthographic(Screen.Width, Screen.Height, -1, 1000);

            //basicEffect.View = ViewMatrix = Matrix.CreateLookAt(new Vector3(Screen.Width / 2, Screen.Height / 2, -0.5f),
            //                                       new Vector3(Screen.Width / 2, Screen.Height / 2, 10000),
            //                                       new Vector3(0, 1, 0));

            //WorldMatrix = Matrix.Identity;
            ////basicEffect.View = Matrix.CreateLookAt(new Vector3(1, 1, 1),
            ////                                       new Vector3(0, 0, 0),
            ////                                       new Vector3(0, 1, 0));

            ////basicEffect.View = Matrix.Identity;

            //basicEffect = new BasicEffect(Screen.CurrentGraphicsDevice);
            //basicEffect.TextureEnabled = true;

            basicEffect = new AlphaTestEffect(Screen.CurrentGraphicsDevice);
             
            //Vector3 cameraPosition = new Vector3(Screen.CenterScreen, 0);
            //Vector3 cameraTarget = new Vector3(Screen.CenterScreen, 100);
            //Vector3 cameraUp = Vector3.UnitY;
            //float nearClippingDistance = 0.1f;
            //float farClippingDistance = 1000f;
            //float fieldOfView = MathHelper.ToRadians(45.0f);
            //float aspectRatio = (float)Screen.Width / (float)Screen.Height;

            //worldMatrix = Matrix.Identity;
            //viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget, cameraUp);
            //projectionMatrix = Matrix.CreatePerspectiveFieldOfView(fieldOfView, aspectRatio, nearClippingDistance, farClippingDistance);

            viewMatrix = Matrix.CreateLookAt(
    new Vector3(0.0f, 0.0f, 1.0f),
    Vector3.Zero,
    Vector3.Up
    );

            projectionMatrix = Matrix.CreateOrthographicOffCenter(
                0,
                (float)Screen.Width,
                (float)Screen.Height,
                0,
                1.0f, 1000.0f);

            vertex = new VertexPositionColorTexture[0];
            GrowBuffer(100);

            dstate = new DepthStencilState();
            dstate.DepthBufferEnable = true;
            dstate.DepthBufferFunction = CompareFunction.Greater;
            dstate.DepthBufferWriteEnable = true;

            bstate = new BlendState();
            bstate.AlphaBlendFunction = BlendFunction.Add;
            bstate.AlphaDestinationBlend = Blend.One;
            bstate.AlphaSourceBlend = Blend.One;


            
            
        }

        DepthStencilState dstate;

        BlendState bstate;


        void GrowBuffer(int size) 
        {
            VertexPositionColorTexture[] buff = vertex;
            vertex = new VertexPositionColorTexture[size];
            buff.CopyTo(vertex, 0);
        }

        Matrix worldMatrix = Matrix.Identity;

        public Matrix WorldMatrix
        {
            get { return worldMatrix; }
            set { worldMatrix = value; }
        }

        Matrix viewMatrix = Matrix.Identity;

        public Matrix ViewMatrix
        {
            get { return viewMatrix; }
            set { viewMatrix = value; }
        }

        Matrix projectionMatrix = Matrix.Identity;

        public Matrix ProjectionMatrix
        {
            get { return projectionMatrix; }
            set { projectionMatrix = value; }
        }

        //BasicEffect basicEffect;
        AlphaTestEffect basicEffect;
        VertexPositionColorTexture[] vertex;
        int count;

        RasterizerState rstate = new RasterizerState() { CullMode = CullMode.None };

        public void Begin() 
        {
            count = 0;
            usedTexture = Texture;
        }

        public void End() 
        {
            Flush();
            Reset();
        }

        public Texture2D Texture { get; set; }

        Texture2D usedTexture;

        public void Flush() 
        {
            Screen.CurrentGraphicsDevice.RasterizerState = RasterizerState.CullNone;
            Screen.CurrentGraphicsDevice.BlendState = BlendState.AlphaBlend;
            Screen.CurrentGraphicsDevice.DepthStencilState = dstate;


            //basicEffect.Parameters["Texture"].SetValue(usedTexture);
            //basicEffect.Parameters["WorldViewProj"].SetValue(worldMatrix * viewMatrix * projectionMatrix);

            basicEffect.World = WorldMatrix;
            basicEffect.Texture = usedTexture;
            basicEffect.View = ViewMatrix;
            basicEffect.Projection = ProjectionMatrix;

            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                Screen.CurrentGraphicsDevice.DrawUserPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, vertex, 0, count / 3);
            }

            count = 0;
        }

        public void Reset() 
        {

        }

        public void DrawImage(AtlasQuad quad) 
        {
            if (count + 6 > vertex.Length)
                GrowBuffer(vertex.Length);
            vertex[count + 0] = quad.vertexs[0];
            vertex[count + 1] = quad.vertexs[1];
            vertex[count + 2] = quad.vertexs[2];
            vertex[count + 3] = quad.vertexs[0];
            vertex[count + 4] = quad.vertexs[2];
            vertex[count + 5] = quad.vertexs[3];
            count += 6;
        }
    }
}
